/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef OLA_SDK_API_H
#define OLA_SDK_API_H

#include <stdint.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef enum {
    OLA_LOG_LEVEL_MIN = 0,
    OLA_LOG_LEVEL_EMERG,
    OLA_LOG_LEVEL_ALERT,
    OLA_LOG_LEVEL_CRIT,
    OLA_LOG_LEVEL_ERROR,
    OLA_LOG_LEVEL_WARNING,
    OLA_LOG_LEVEL_NOTICE,
    OLA_LOG_LEVEL_INFO,
    OLA_LOG_LEVEL_DEBUG,
} OlaLogLevel;

typedef enum {
    OLA_NETCFG_PROTOCOL_NONE = 0,
    OLA_NETCFG_PROTOCOL_TYPE_SOFTAP,
} OlaNetcfgProtocol;

typedef enum {
    OLA_DEV_AUTH_TYPE_CERT = 0,
    OLA_DEV_AUTH_TYPE_LICENSE,
} OlaDevAuthType;

/* 设备安全协商方式 */
typedef enum {
    OLA_SEC_NEGO_TYPE_SPEKE = 0,
    OLA_SEC_NEGO_TYPE_JPAKE,
    OLA_SEC_NEGO_TYPE_PECDH,
} OlaSecNegotiationType;

/* 使用PIN码时，PIN码的来源 */
typedef enum {
    OLA_PINCODE_TYPE_DEFAULT = 0,
    OLA_PINCODE_TYPE_OUTSIDE
} OlaPinCodeType;

/* 安全协商时，使用PIN码、QR码 */
typedef enum {
    OLA_DEV_CODE_CAP_PIN_CODE = 0,
    OLA_DEV_CODE_CAP_QR_CODE,
    OLA_DEV_CODE_CAP_PIN_QR_BOTH,
} OlaDevCodeCap;

typedef struct {
    /* 任务栈大小 */
    unsigned int taskSize;
    /* 任务优先级 */
    int taskPriority;
} OlaMainTaskParam;

typedef struct {
    /* 日志等级 */
    OlaLogLevel logLevel;
    /* coap接收缓冲区大小 */
    unsigned int coapRecvBufSize;
    /* coap发送缓冲区大小 */
    unsigned int coapSendBufSize;
} OlaRuningParam;

typedef struct {
    OlaSecNegotiationType negoType;
    OlaDevCodeCap codeCap;
    OlaPinCodeType pinCodeType;
    OlaNetcfgProtocol protocol;
    OlaDevAuthType authType;
    unsigned int timeout;
    const char *customSsidData;     /* ssid末尾携带的厂商自定义数据，依据实际情况截断，长度[0, 12] */
} OlaNetCfgParam;

typedef enum {
    OLA_PROTOCOL_TYPE_NONE = 0,
    OLA_PROTOCOL_TYPE_WIFI,
    OLA_PROTOCOL_TYPE_ZWAVE,
    OLA_PROTOCOL_TYPE_ZIGBEE,
    OLA_PROTOCOL_TYPE_BLE,
    OLA_PROTOCOL_TYPE_PLC,
    OLA_PROTOCOL_TYPE_BLE_MESH,
    OLA_PROTOCOL_TYPE_NFC,
    OLA_PROTOCOL_TYPE_BLE_AND_WIFI,
    OLA_PROTOCOL_TYPE_MAX
} OlaProtocolType;

typedef struct {
    const char *sn;         /* 设备序列号，长度(3,40] */
    const char *model;      /* 设备型号，长度(0,32] */
    const char *catID;      /* 品类ID，长度4 */
    const char *vendorID;   /* 厂商ID，长度4 */
    const char *devName;    /* 设备名，长度(0,256] */
    const char *prodId;     /* 产品ID，长度4 */
    const char *mac;        /* 产品MAC，长度(0,16] */
    const char *fwv;        /* 产品固件版本号，长度(0,64] */
    const char *hwv;        /* 产品硬件版本号，长度(0,64] */
    const char *swv;        /* 产品软件版本号，长度(0,64] */
    const char *manuName;   /* 厂商名，长度4 */
    const char *platformId; /* 平台ID，长度2 */
    OlaProtocolType type;
} OlaDevParam;

typedef struct {
    OlaMainTaskParam taskPara;
    OlaDevParam devPara;
    OlaNetCfgParam netcfgPara;
    OlaRuningParam runingPara;
} OlaInitParam;

typedef struct {
    unsigned char *data;
    unsigned int len;
} OlaData;

typedef struct {
    unsigned char *buf;
    unsigned int len;
    unsigned int size;
} OlaBuffer;

typedef enum {
    OLA_EVENT_CODE_START = 0,
    OLA_EVENT_CODE_RESET,
    OLA_EVENT_CODE_STOP,
    OLA_EVENT_CODE_NETCFG_WAITING,
    OLA_EVENT_CODE_NETCFG_START,
    OLA_EVENT_CODE_NETCFG_SUCCESS,
    OLA_EVENT_CODE_NETCFG_TIMEOUT,
    OLA_EVENT_CODE_NETCFG_FAIL,
    OLA_EVENT_CODE_NETWORK_WAITING,
    OLA_EVENT_CODE_NETWORK_WAITING_TIMEOUT,
    OLA_EVENT_CODE_NETWORK_CONNECTED,
    OLA_EVENT_CODE_M2M_AUTH_START,
    OLA_EVENT_CODE_M2M_AUTH_FAIL,
    OLA_EVENT_CODE_M2M_AUTH_SUCCESS,
    OLA_EVENT_CODE_M2M_REG_START,
    OLA_EVENT_CODE_M2M_REG_FAIL,
    OLA_EVENT_CODE_M2M_REG_SUCCESS,
    OLA_EVENT_CODE_M2M_LOGIN_START,
    OLA_EVENT_CODE_M2M_LOGIN_FAIL,
    OLA_EVENT_CODE_M2M_LOGIN_SUCCESS,
    OLA_EVENT_CODE_M2M_CLOUD_OFFLINE,
    OLA_EVENT_CODE_M2M_CLOUD_UNREG,
    OLA_EVENT_CODE_DEVICE_REVOKE,
} OlaEventCode;

typedef enum {
    OLA_DATA_TYPE_JSON_DEVICE_MODEL = 0,
    OLA_DATA_TYPE_NETCFG_PINCODE,
    OLA_DATA_TYPE_AUTH_DEVICE_LICENSE,
    OLA_DATA_TYPE_AUTH_DEVICE_CERT_CHAIN,
    OLA_DATA_TYPE_AUTH_DEVICE_PRIVATE_KEY,
    OLA_DATA_TYPE_AUTH_ROOT_CERT,
    OLA_DATA_TYPE_STORAGE_KEY_MATERIAL,
    OLA_DATA_TYPE_UNIQUE_ID,
} OlaDeviceDataType;

typedef enum {
    OLA_RUNING_STATE_NOT_RUNING = 0,
    OLA_RUNING_STATE_NETCFG,
    OLA_RUNING_STATE_WAITING_NETWORK_CONNECTED,
    OLA_RUNING_STATE_CONNECT_CLOUD,
    OLA_RUNING_STATE_M2M_RUNING,
} OlaRuningState;

typedef enum {
    OLA_REGISTER_STATE_REG = 0,
    OLA_REGISTER_STATE_UNREG,
} OlaRegisterState;

typedef enum {
    OLA_QUERY_TYPE_REGISTER_STATE = 0,
    OLA_QUERY_TYPE_RUNING_STATE,
} OlaQueryType;

typedef union {
    OlaRegisterState regState;
    OlaRuningState runingState;
} OlaQueryData;

typedef void* OlaReqId;

typedef struct {
    /*
     * 功能: 获取设备相关数据
     * 参数: type，获取数据的类型
     *       out，获取到的数据，由开发者申请内存，ola释放
     * 返回: 0，获取成功
     *       非0，获取失败
     */
    int (*getDeviceData)(OlaDeviceDataType type, OlaData *out);

    /*
     * 功能: 服务属性修改/方法执行
     * 参数: json，包含服务属性或动作的json结构体
     *       id，执行的动作id
     * 返回: 0，执行成功
     *       -1，执行失败
     *       1，异步执行
     */
    int (*ctrlDeviceService)(const OlaData *json, OlaReqId id);

    /*
     * 功能: 服务属性查询
     * 参数: json，服务属性的json结构体
     *       out，查询到的属性json结构体，由开发者申请内存，ola释放
     * 返回: 0，查询成功
     *       -1，查询失败
     */
    int (*queryDeviceService)(const OlaData *json, OlaData *out);

    /*
     * 功能: SDK状态通知
     * 参数: code，当前的状态码
     */
    void (*notifySdkEvent)(OlaEventCode code);

    /*
     * 功能: 诊断信息输出
     * 参数: errcode，诊断信息错误码
     *       msg，诊断信息
     */
    void (*diagnosisLogOutput)(unsigned int errcode, const OlaData *msg);
} OlaCallback;

typedef struct {
    /*
     * 功能: 启动OLA SDK
     * 返回: 0，启动成功
     *       非0，启动失败
     */
    int (*start)(void);

    /*
     * 功能: 停止OLA SDK
     * 返回: 0，停止成功
     *       非0，停止失败
     * 注意: 该接口阻塞实现
     */
    int (*stop)(void);

    /*
     * 功能: 复位OLA SDK
     * 返回: 0，复位成功
     *       非0，复位失败
     * 注意: 该接口阻塞实现
     */
    int (*reset)(void);

    /*
     * 功能: 恢复出厂设置
     * 返回: 0，恢复出厂成功
     *       非0，恢复出厂失败
     */
    int (*restore)(void);

    /*
     * 功能: 查询OLA SDK相关状态
     * 参数: type，查询类型
     *       data，出参，查询到的结果
     * 返回: 0，查询成功
     *       非0，查询失败
     */
    int (*query)(OlaQueryType type, OlaQueryData *data);

    /*
     * 功能: 设置日志等级
     * 参数: level，日志等级
     * 返回: 0，设置成功
     *       非0，设置失败
     */
    int (*setLogLevel)(OlaLogLevel level);

    /*
     * 功能: 上报服务属性/事件
     * 参数: json，待上报的json数据
     *       id，异步控制时携带的标识符
     * 返回: 0，上报成功
     *       非0，上报失败
     */
    int (*reportService)(const OlaData *json, OlaReqId id);
} OlaLifeCycleManger;

const OlaLifeCycleManger *OlaInit(const OlaInitParam *para, const OlaCallback *cb);

int OlaDeinit(void);

#ifdef __cplusplus
}
#endif

#endif /* OLA_SDK_API_H */